/* Copyright (c) 2008, RDFfs - Andrea Marchesini <baku@morlardf.net>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the <organization> nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#include <glib.h>
#include <redland.h>

#define FUSE_USE_VERSION 26
#include <fuse.h>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>

#define LICENSE			"BSD"
#define AUTHOR			"Andrea Marchesini"

#define RDF_VERSION_STRING	PACKAGE " " VERSION " - " LICENSE "\n"

#define RDF_SUBJECT_DIR			"subjects"
#define RDF_BNODE_DIR			"bnodes"
#define RDF_TRIPLES_DIR			"triples"

#define RDF_VERSION_FILE		"version"

#define RDF_INPUT_DIR			"input"
#define RDF_INPUT_SOURCE_FILE		"source"
#define RDF_INPUT_FORMATS_DIR		"formats"
#define RDF_INPUT_FORMATS_XML_FILE	"xml"
#define RDF_INPUT_FORMATS_TURTLE_FILE	"turtle"
#define RDF_INPUT_FORMATS_NTRIPLES_FILE	"ntriples"
#define RDF_INPUT_ERROR_FILE		"error"

#define RDF_SUBJECT_FILE		"subject"
#define RDF_PREDICATE_FILE		"predicate"
#define RDF_LANG_FILE			"language"
#define RDF_DATATYPE_FILE		"datatype"
#define RDF_TYPE_FILE			"type"
#define RDF_OBJECT_FILE			"object"

struct
{
  /* List of triples with a resource subject: */
  GList *	subjects;
  guint		subjects_size;

  /* List of triples with a bnode subject: */
  GList *	bnodes;
  guint		bnodes_size;

  /* The input RDF Document: */
  gchar *	input;
  gsize		input_size;

  /* The filename of the RDF Document: */
  gchar *	filename;

  /* XML format: */
  gchar *	format_xml;
  gsize		format_xml_size;

  /* TURTLE format: */
  gchar *	format_turtle;
  gsize		format_turtle_size;

  /* NTRIPLES format: */
  gchar *	format_ntriples;
  gsize		format_ntriples_size;

  /* Parser error: */
  gchar *	error;
  gsize		error_size;

  /* Mutex and counter for the reader/writer algorithm: */
  GMutex *	mutex_reader;
  GMutex *	mutex_writer;
  guint		readers;

} rdffs_input;

enum rdffs_format_t
{
  RDF_FORMAT_XML,
  RDF_FORMAT_TURTLE,
  RDF_FORMAT_NTRIPLES
};

enum rdffs_object_t
{
  RDF_OBJECT_BNODE,
  RDF_OBJECT_LITERAL,
  RDF_OBJECT_RESOURCE
};

struct rdffs_t
{
  gchar *	subject;
  gsize		subject_size;

  GList *	triples;
};

struct rdffs_link_t
{
  gboolean		is_bnode;
  gint			number;
  struct rdffs_t *	subject;
};

struct rdffs_triple_t
{
  gchar *		predicate;
  gsize			predicate_size;
  struct rdffs_link_t	predicate_link;

  gchar *		object;
  gsize			object_size;
  enum rdffs_object_t	object_type;
  struct rdffs_link_t	object_link;

  gchar *		lang;
  gsize			lang_size;

  gchar *		datatype;
  gsize			datatype_size;
  struct rdffs_link_t	datatype_link;
};

struct fuse_operations rdffs_oper;

/* Prototypes **************************************************************/
void		rdffs_free 		(struct rdffs_t *	rdf);

void		rdffs_triple_free	(struct rdffs_triple_t * triple);

void		rdffs_destroy_data	(void);

void		rdffs_destroy		(void *			dummy);

gboolean	rdffs_parse		(gchar *		buffer,
					 gchar *		file,
					 enum rdffs_format_t	format,
					 gchar **		error,
					 gsize *		error_size);

gboolean	rdffs_write		(gchar *		file,
					 enum rdffs_format_t	format,
					 gchar **		buffer,
					 gsize *		size,
					 gchar **		error,
					 gsize *		error_size);

void		rdffs_lock_writer	(void);

void		rdffs_unlock_writer	(void);

void		rdffs_lock_reader	(void);

void		rdffs_unlock_reader	(void);

/* EOF */
